var fileInp = document.querySelector("#file");
var submitBtn = document.querySelector("#btn");
var nowFile;
fileInp.onchange = async function (e) {
    nowFile = fileInp.files[0];
}

submitBtn.addEventListener('click', async function (e) {
    if (!nowFile) return;
    var result =await createchuck(nowFile, 10 * 1024 * 1024);
    var hash =await calchash(result)
    // 请求文件状态
    const res = await chuckStatus(hash, result.length)
    if (res.type === 5) {
        alert("文件已上传");
        return;
    }
    if (res.type === 2 || res.type === 4) {
        var canMerge = false;
        for (let i = 0; i < result.length; i++) {
            var ress = await uploadSingleChunks(i, result[i], hash);
            if (ress.chuckList.length == result.length) {
                canMerge = true;
                break;
            }
        }
        if (canMerge) {
            const resss = await mergeChunks(hash, nowFile.name);
            if (resss.url) alert("上传完毕")
        }
    }
})

/**
 * @description 传入文件以及每片的大小
 * @param {File} file 文件
 * @param {number} chuckSize 切片容量 
 * @returns 切片数组
 */
function createchuck(file, chuckSize) {
    // 切片合集
    var result = [];
    // 每切一片，向前移动一个切片单位
    for (let i = 0; i < file.size; i += chuckSize) {
        // 会产生一个blob类型的文件数据
        result.push(file.slice(i, i + chuckSize));
    }
    return result;
}
/**
 * @description 使用spark-md5进行文件哈希值的增量计算
 * @param {Blob[]} chunks 文件切片数组
 * @returns 计算好的哈希值
 */
function calchash(chunks) {
    return new Promise(resolve => {
        const spark = new SparkMD5.ArrayBuffer()
        function _read(i) {
            if (i >= chunks.length) {
                // 读取完成，返回最终的hash值
                resolve(spark.end());
                return;
            }
            const blob = chunks[i];
            const reader = new FileReader();
            reader.onload = e => {
                // 读取到字节数组
                // 执行增量哈希计算
                spark.append(e.target.result);
                _read(i + 1);
            }
            reader.readAsArrayBuffer(blob);
        }
        _read(0);
    })
}

const Ajax = {
    baseUrl: "http://127.0.0.1:8002/api/v1/",
    get: function (url, callback) {
        let xhr = new XMLHttpRequest();
        xhr.open('GET', this.baseUrl + url, false);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
                callback(xhr.responseText);
            }
        }
        xhr.send();
    },
    upload: function (url, formData, callback) {
        let xhr = new XMLHttpRequest();
        xhr.open('POST', this.baseUrl + url, false);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
                callback(xhr.responseText);
            }
        }
        xhr.send(formData);
    }
}

// 请求文件传输状态
async function chuckStatus(hash, length) {
    var result;
    await Ajax.get(`slice/?hash=${hash}&length=${length}`, (res) => {
        result = JSON.parse(res);
    })
    return result;
}

// 上传文件
async function uploadSingleChunks(index, file, hash) {
    var formData = new FormData();
    formData.append("file", file);
    formData.append("hash", hash);
    var result;
    await Ajax.upload(`slice/${index}`, formData, (res) => {
        result = JSON.parse(res);
    })
    return result;
}

// 合并文件
async function mergeChunks(hash, fileName) {
    var result;
    await Ajax.get(`slice/merge?hash=${hash}&fileName=${fileName}`, (res) => {
        result = JSON.parse(res);
    })
    return result;
}